package com.topscomm.tap.common;

import com.topscomm.basic.IBasicService;
import com.topscomm.cbo.pojo.*;
import com.topscomm.cbo.service.ICboItemsService;
import com.topscomm.pub.util.ConvertUtil;
import com.topscomm.pub.util.SpringUtil;
import com.topscomm.pub.util.StringBufferProxy;
import com.topscomm.pub.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.io.Serializable;
import java.util.*;

/**
 * @author: zhangsui
 * @date: 2016年3月31日上午10:50:29
 * @description:代码值缓存池
 * @modify:
 */
@Component(value = "localDataCodeCache")
@Scope(value = "prototype")
public class LocalDataCodeCache extends DatacodeCache implements Serializable {
    /**
     * @type: long
     * @description:
     */
    private static final long serialVersionUID = 1L;
    private final Map<String, CboItemsEntity> itemCache = new HashMap<String, CboItemsEntity>();
    private final Map<String, List<Map<String, Object>>> itemDetailCache = new HashMap<String, List<Map<String, Object>>>();
    @Autowired
    private RedisDatacodeStore redisDatacodeStore;

    // 这些表的编码数据，进行强制缓存（若有新增数据，会判断进行强制刷新）
    private static final List<String> cacheTableCode = new ArrayList<>();
    static {
        cacheTableCode.add(CboUserEntity.tableName);
        cacheTableCode.add(CboDeptEntity.tableName);
        cacheTableCode.add(CboApprovalNodeEntity.tableName);
    }
    /**
     * @author: zhangsui
     * @date: 2016年3月31日上午10:51:38
     * @param itemCode
     * @param values
     * @param inCol
     * @param outCol
     * @return
     * @return_type: String
     * @description:批量转换显示值
     * @modify:
     */
    @Override
    public String getValueDynamic(String itemCode, String[] values, String inCol, String outCol) {
        if (values == null || values.length <= 0) {
            return "";
        }
        StringBufferProxy resultValue = new StringBufferProxy();
        for (String value : values) {
            String tempValue = getValueDynamic(itemCode, value, inCol, outCol);
            if (!StringUtil.isEmpty(tempValue)) {
                resultValue.appendSingle("{0},", tempValue);
            }
        }
        if (resultValue.length() > 0) {
            resultValue = resultValue.substring(0, resultValue.length() - 1);
        }
        return resultValue.toString();
    }

    /**
     * @author: zhangsui
     * @date: 2016年3月31日上午10:51:38
     * @param itemCode
     * @param value
     * @param inCol
     * @param outCol
     * @return
     * @return_type: String
     * @description:转换显示值
     * @modify:
     */
    @Override
    public String getValueDynamic(String itemCode, String value, String inCol, String outCol) {
        if (value == null) {
            return "";
        }
        // 加载item明细
        List<Map<String, Object>> mapList = null;
        if (!this.itemDetailCache.containsKey(itemCode)) {
            mapList = this.getCodeListMap(itemCode);
            this.itemDetailCache.put(itemCode, mapList);
        } else {
            mapList = this.itemDetailCache.get(itemCode);
        }
        if (mapList == null || mapList.size() <= 0) {
            return "";
        }
        // 转换值
        /********************* 并行实现 *********************/
        if (value.indexOf(",") == -1) {
            String valueString = queryValue(itemCode, mapList, value, inCol, outCol);
            if (valueString != null) {
                return valueString;
            }
        } else {
            String returnValueString = "";
            String[] valueList = value.split(",");
            for (String val : valueList) {
                String valueString = queryValue(itemCode, mapList, val, inCol, outCol);
                if (valueString != null) {
                    returnValueString += "," + valueString;
                }
            }
            if (returnValueString.length() > 0) {
                returnValueString = returnValueString.substring(1);
            }
            return returnValueString;
        }
        return "";
    }

    /**
     * @description:获取值
     * @param mapList
     * @param value
     * @param inCol
     * @param outCol
     * @return
     * @author: zhanglongfei
     * @date: 2021年3月23日下午1:44:22
     * @modify:
     */
    private String queryValue(String itemCode, List<Map<String, Object>> mapList, String value, String inCol,
            String outCol) {
        Optional<Map<String, Object>> resultOptional = mapList.parallelStream().filter(dataMap -> {
            String tempValue = ConvertUtil.convertToString(dataMap.get(inCol));
            return tempValue.equals(value);
        }).findFirst();
        if (resultOptional.isPresent()) {
            Map<String, Object> resultDataMap = resultOptional.get();
            if (resultDataMap != null) {
                return ConvertUtil.convertToString(resultDataMap.get(outCol));
            }
        }
        // else if (itemDetailCache.containsKey(itemCode) &&
        // redisDatacodeStore.existKey(itemCode)) {
        // itemDetailCache.remove(itemCode);
        // redisDatacodeStore.removeKey(itemCode);
        // mapList = this.getCodeListMap(itemCode);
        // return queryValue(itemCode, mapList, value, inCol, outCol);
        // }
        return null;
    }

    /**
     * @author: zhangsui
     * @date: 2016年3月31日上午10:54:13
     * @param itemCode
     * @return
     * @return_type: List<Map>
     * @description:通过代码编码获取代码明细集合
     * @modify:
     */
    @Override
    public List<Map<String, Object>> getCodeListMap(String itemCode) {
        return getCodeListMap(itemCode, "");
    }

    /**
     * @author: zhangsui
     * @date: 2016年3月31日上午10:53:53
     * @param ItemCode
     * @param sqlWhere
     * @return
     * @return_type: List<Map>
     * @description:通过代码编号、Where条件获取代码明细集合
     * @modify:
     */
    @Override
    public List<Map<String, Object>> getCodeListMap(String ItemCode, String sqlWhere) {
        return getCodeListMap(ItemCode, sqlWhere, "");
    }

    /**
     * @author: zhangsui
     * @date: 2016年3月31日上午10:54:13
     * @param itemCode
     * @param sqlWhere
     * @param order
     * @return
     * @return_type: List<Map>
     * @description:通过代码编号、Where条件、Order条件来获取代码明细集合
     * @modify:
     */
    @Override
    public List<Map<String, Object>> getCodeListMap(String itemCode, String sqlWhere, String order) {
        List<Map<String, Object>> mapList = redisDatacodeStore.queryData(itemCode);
        if (mapList != null) {
            return mapList;
        }
        // 查询item对象
        CboItemsEntity item = this.getItemEntity(itemCode);
        if (item == null) {
            return new ArrayList<Map<String, Object>>();
        }
        // 获取service对象
        IBasicService<?, ?> service = this.getServiceInstance(item);
        // 查询item明细
        StringBufferProxy sql = new StringBufferProxy();
        if (item.getTargettable().equals(CboItemDetailsEntity.tableName)) {
            sql.appendLineSingle(" itemid = '{0}'", item.getId());
        } else {
            sql.appendLineSingle(" 1=1 ");
        }
        if (!StringUtil.isEmpty(item.getTargetcondition())) {
            sql.appendSingle(" and {0} ", item.getTargetcondition());
        }
        if (!StringUtil.isEmpty(sqlWhere.trim())) {
            sql.appendSingle(" and {0} ", sqlWhere);
        }
        if (!StringUtil.isEmpty(order)) {
            sql.appendSingle(" order by {0} ", order);
        }
        List<String> filedList = new ArrayList<String>();
        filedList.add(item.getIdcol() + " as id");
        filedList.add(item.getCodecol() + " as code");
        filedList.add(item.getNamecol() + " as name");
        mapList = service.queryMapFieldsByWhere(sql.toString(), filedList);
        if (CboItemDetailsEntity.tableName.equals(item.getTargettable())) {
            redisDatacodeStore.storeData(itemCode, mapList);
        } else if (cacheTableCode.contains(item.getTargettable())) {
            redisDatacodeStore.storeData(itemCode, mapList);
        }
        return mapList;
    }

    /**
     * @author: zhangsui
     * @date: 2018年1月23日下午6:10:11
     * @description:清理缓存
     * @modify:
     */
    public static void clearCache() {
    }

    /**
     * @author: zhangsui
     * @date: 2018年1月25日下午5:47:01
     * @description:代码对象
     * @modify:
     */
    @Override
    protected CboItemsEntity getItemEntity(String itemCode) {
        if (!this.itemCache.containsKey(itemCode)) {
            StringBufferProxy sql = new StringBufferProxy();
            sql.appendLineSingle(" code='{0}' ", itemCode);
            ICboItemsService cboItemsService = (ICboItemsService) getServiceInstance("cboItemsService");
            CboItemsEntity item = cboItemsService.queryObjectByWhere(sql.toString());
            this.itemCache.put(itemCode, item);
        }
        return this.itemCache.get(itemCode);
    }

    /**
     * @author: zhangsui
     * @date: 2018年1月24日下午6:18:10
     * @description: 创建服务实例
     * @modify:
     */
    private IBasicService<?, ?> getServiceInstance(CboItemsEntity item) {
        String serviceName = item.getTargettable() + "Service";
        serviceName = StringUtil.lowerFirst(serviceName);
        return getServiceInstance(serviceName);
    }

    /**
     * @author: zhangsui
     * @date: 2018年1月24日下午6:18:10
     * @description: 创建服务实例
     * @modify:
     */
    private IBasicService<?, ?> getServiceInstance(String serviceName) {
        IBasicService<?, ?> service = (IBasicService<?, ?>) SpringUtil.getBean(serviceName);
        return service;
    }
}
